/* eslint-disable import/named */
/* eslint-disable import/no-cycle */
/* eslint-disable prefer-promise-reject-errors */
// 工具类存取
import Axios from 'axios';
import { Toast } from 'vant';
import crypto from '../utils/crypto';
import global from '../utils/global';

Axios.defaults.withCredentials = true;
function getBaseUrl() {
  let pathName = process.env.VUE_APP_PATH;
  if (window.location.hostname === '9.23.28.81') {
    // 测试地址访问服务器实地址，需要转换工程路径
    pathName = '/elec_claim';
  }
  return `${window.location.origin}${pathName}`;
  // return window.location.hostname === process.env.VUE_APP_WEBHOST ? process.env.VUE_APP_BASEURL_INTRANET : process.env.VUE_APP_BASEURL;
}

export const other = '';

export class RequestModel {
  constructor(options) {
    this.options = {
      loadingFlag: true,
      encryptFlag: true,
      axiosOptions: {
        method: 'post',
        url: getBaseUrl(),
        params: '',
        data: '',
        timeout: 300000,
        headers: {
          'Content-Type': 'application/json',
        },
      },
    };
    this.requestInfo = {};
    if (options && options.axiosOptions) {
      Object.assign(options.axiosOptions, this.options.axiosOptions, options.axiosOptions);
    }
    Object.assign(this.options, options);
    this.onError = (this.options.onError && this.options.onError.bind(this)) || this.onError;
    this.onSuccess = (this.options.onSuccess && this.options.onSuccess.bind(this)) || this.onSuccess;
  }

  showRequestInfo() {
    utils.logInfo(this.requestInfo);
  }

  chageSuccessFun(fun) {
    this.onSuccess = fun;
  }

  changeErrorFun(fun) {
    this.onError = fun;
  }

  chageOptions(options) {
    Object.assign(this.options, options);
  }

  loadingShow() {
    if (this.options.loadingFlag) {
      // EventBus.commit('showLoading');
    }
  }

  loadingHiden() {
    if (this.options.loadingFlag) {
      // EventBus.commit('hideLoading');
    }
  }

  // eslint-disable-next-line class-methods-use-this
  onSuccess(res) {
    // 成功回调
    if (res.data && res.data.header && res.data.header.statusCode && (res.data.header.statusCode === '000000')) {
      if (res.data.body && (JSON.stringify(res.data.body) !== '{}')) {
        const result = this.decryptParams(res.data.body);
        this.requestInfo.response = result;
        this.showRequestInfo();
        return result || true;
      }
      this.requestInfo.response = res.data.body;
      this.showRequestInfo();
      return true;
    }
    if (res.data && res.data.header && res.data.header.message) {
      Toast({
        title: '错误提示',
        message: res.data.header.message,
      });
      this.showRequestInfo();
      return false;
    }
    this.showRequestInfo();
    return res;
  }

  // eslint-disable-next-line class-methods-use-this
  onError(err, options) {
    // 错误回调
    utils.logError({
      kind: 'error',
      errorMsg: err,
      params: options,
    });
  }

  encryptParams(params) {
    // 加密
    if (!params) {
      return null;
    }
    if (!this.options.encryptFlag) {
      return params;
    }
    const key = crypto.generateKey(16);
    this.key = key;
    const rasKey = crypto.encryptByRSA(key, global.rsaPublicKey);
    const aesBody = crypto.encryptByAES(JSON.stringify(params), key);
    Object.assign(this.options.axiosOptions.headers, {
      interceptor: rasKey,
    });
    return aesBody;
  }

  decryptParams(params) {
    // 解密
    if (!this.options.encryptFlag) {
      return params;
    }
    if (!params) {
      return params;
    }
    return JSON.parse(crypto.decryptByAES(params, this.key));
  }

  // 请求方法 paramsData {
  //   $params: params形式传参
  //   $data: data形式传递参数
  // }
  send(paramsArg, url) {
    const paramsData = {
      params: paramsArg.$params,
      data: paramsArg.$data,
    };
    return new Promise((resolve) => {
      this.loadingShow();
      const encryptParams = this.encryptParams(paramsData.params);
      const encryptData = this.encryptParams(paramsData.data);
      this.requestInfo = {
        ...this.requestInfo,
        requestUrl: this.options.axiosOptions.url + url,
        params: paramsData.params,
        data: paramsData.data,
        encryptParams,
        encryptData,
        key: this.key,
        axiosOptions: this.options.axiosOptions,
      };
      const options = {
        ...this.options.axiosOptions,
        url: this.options.axiosOptions.url + url,
        params: encryptParams,
        data: encryptData,
      };
      Axios(options)
        .then(res => {
          // EventBus.commit('hideLoading');
          resolve(this.onSuccess(res));
        })
        .catch(err => {
          // EventBus.commit('hideLoading');
          resolve(this.onError(err, this.requestInfo));
        });
    });
  }
}
